package com.example.demo7.controller;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.ApiAssert;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.api.ApiResult;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo7.ErrorCode;
import com.example.demo7.entity.DetectionOrganizationDto;
import com.example.demo7.entity.User;
import com.example.demo7.entity.enums.AgeEnum;
import com.example.demo7.entity.enums.PhoneEnum;
import com.example.demo7.service.IUserService;
import com.example.demo7.util.ExcelBean;
import com.example.demo7.util.ExcelUtils;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.beans.IntrospectionException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * 代码生成器，参考源码测试用例：
 * <p>
 * /mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/generator/MysqlGenerator.java
 */
@RestController
@RequestMapping("/user")
public class UserController extends ApiController {

    @Autowired
    private IUserService userService;

    /**
     * <p>
     * 测试通用 Api Controller 逻辑
     * </p>
     * 测试地址：
     * http://localhost:8080/user/api
     * http://localhost:8080/user/api?test=mybatisplus
     */
    @GetMapping("/api")
    public ApiResult<Object> testError(String test, HttpServletRequest request) {
        ApiAssert.notNull(ErrorCode.TEST, test);
        HttpSession session = request.getSession();
        Object user1 = session.getAttribute("msg");
        System.out.println(user1);
        return success(user1);
    }

    /**
     * http://localhost:8080/user/test
     */
    @GetMapping("/test")
    public IPage<User> test() {
        QueryWrapper<User> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.like("name", "三");
        objectQueryWrapper.eq("age", 2);
        objectQueryWrapper.or(c -> c.like("name", "张"));
        IPage<User> page = userService.page(new Page<User>(0, 12), objectQueryWrapper);
        return page;
    }

    /**
     * http://localhost:8080/user/test
     */
    @GetMapping("/testa")
    public void testa(HttpServletResponse response) throws IllegalAccessException, IntrospectionException, InvocationTargetException {

        IPage<User> page = userService.page(new Page<User>(0, 12), null);
        List<User> userList = page.getRecords();
        List<DetectionOrganizationDto> list=new ArrayList<>();
        Map<Integer, List<ExcelBean>> mapEX = new LinkedHashMap<>();
        List<ExcelBean> ems = new ArrayList<>();
        ems.add(new ExcelBean("基因检测机构", "supplierName", 0));
        ems.add(new ExcelBean("账号", "superUserName", 0));
        ems.add(new ExcelBean("密码", "password", 0));
        ems.add(new ExcelBean("联系人", "consigneeName", 0));
        ems.add(new ExcelBean("手机号", "consigneePhone", 0));
        ems.add(new ExcelBean("省", "provinceId", 0));
        ems.add(new ExcelBean("收货地址", "consignAddress", 0));
        mapEX.put(0, ems);
        //XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFWorkbook sheet1 = ExcelUtils.createExcelFile(DetectionOrganizationDto.class, list, mapEX, "sheet1",0);
        //响应到客户端
        try {
            this.setResponseHeader(response, "c测试.xlsx");
            OutputStream os = response.getOutputStream();
            sheet1.write(os);
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * http://localhost:8080/user/test
     */
    @GetMapping("/testa1")
    public void testa1(HttpServletResponse response) throws IllegalAccessException, IntrospectionException, InvocationTargetException {

    }




    //发送响应流方法
    public void setResponseHeader(HttpServletResponse response, String fileName) {
        try {
            try {
                fileName = new String(fileName.getBytes(), "ISO8859-1");
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            response.setContentType("application/octet-stream;charset=ISO8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * AR 部分测试
     * http://localhost:8080/user/test1
     */
    @GetMapping("/test1")
    public IPage<User> test1() {
        User user = new User("testAr", AgeEnum.ONE, 1);
        user.setRole(112L);
        user.setTestDate(new Date());
        user.setPhone(PhoneEnum.CMCC);
        user.setName("mybatis-plus-ar2");
        System.out.println(user);
        Class<User> userClass = User.class;
        Field[] declaredFields = userClass.getDeclaredFields();
        Arrays.stream(declaredFields).forEach(field -> {
            System.out.print(field.getName() + ":");
            field.setAccessible(true);
            Object o = null;
            try {
                o = field.get(user);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            System.out.println(o);

        });
        IPage<User> userIPage = new Page<User>(0, 12);
        Wrapper<User> userQueryWrapper = new QueryWrapper<User>();
        IPage<User> page = userService.page(userIPage, null);
        return page;
    }

    @GetMapping("/test12")
    public ApiResult test12() {
        User user = new User();
        user.setName("aaa");
        user.setAge(AgeEnum.TWO);
        user.setTestType(0);
        user.setRole(0L);
        user.setPhone(PhoneEnum.CUCC);
        user.setTestDate(new Date());
        System.out.println(user);
        boolean save = userService.save(user);
        return success(save);
    }

    @GetMapping("/test123")
    public User test123() {
        List<User> users = userService.selectListBySQL();
        System.out.println(users);
        User b = userService.getOne(new QueryWrapper<User>().ge("test_id", 222L));
        User byId = userService.getById(100L);
        User user = new User();
        user.setTestId(1L);
        User user1 = user.selectById();
        return user1;
    }

    /**
     * 增删改查 CRUD
     * http://localhost:8080/user/test2
     */
    @GetMapping("/test2")
    public User test2() {
        System.err.println("删除一条数据：" + userService.removeById(1L));
        System.err.println("deleteAll：" + userService.deleteAll());
        // System.err.println("插入一条数据：" + userService.save(new User(1L, "张三", AgeEnum.TWO, 1)));
        User user = new User("张三", AgeEnum.TWO, 1);
        boolean result = userService.save(user);

        System.err.println("插入一条数据：" + result + ", 插入信息：" + user.toString());
        // System.err.println("查询：" + userService.getById(id).toString());
        //  System.err.println("更新一条数据：" + userService.updateById(new User(1L, "三毛", AgeEnum.ONE, 1)));
        for (int i = 0; i < 5; ++i) {
            //   userService.save(new User(Long.valueOf(100 + i), "张三" + i, AgeEnum.ONE, 1));
        }
        IPage<User> userListPage = userService.page(new Page<User>(1, 5), new QueryWrapper<User>());
        System.err.println("total=" + userListPage.getTotal() + ", current list size=" + userListPage.getRecords().size());

        userListPage = userService.page(new Page<User>(1, 5), new QueryWrapper<User>().orderByDesc("name"));
        System.err.println("total=" + userListPage.getTotal() + ", current list size=" + userListPage.getRecords().size());
        return userService.getById(1L);
    }

    /**
     * 插入 OR 修改
     * http://localhost:8080/user/test3
     */
    @GetMapping("/test3")
    public User test3() {
        User user = new User("王五", AgeEnum.ONE, 1);
        user.setPhone(PhoneEnum.CT);
        userService.saveOrUpdate(user);
        return userService.getById(1L);
    }

    /**
     * http://localhost:8080/user/add
     */
    @GetMapping("/add")
    public Object addUser() {
        User user = new User("张三'特殊`符号", AgeEnum.TWO, 1);
        user.setPhone(PhoneEnum.CUCC);
        return userService.save(user);
    }

    /**
     * http://localhost:8080/user/select_sql
     */
    @GetMapping("/select_sql")
    public Object getUserBySql() {
        return userService.selectListBySQL();
    }

    /**
     * http://localhost:8080/user/select_wrapper
     */
    @GetMapping("/select_wrapper")
    public Object getUserByWrapper() {
        return userService.selectListByWrapper(new QueryWrapper<User>()
                .lambda().like(user -> user.getName(), "毛")
                .or(e -> e.like(User::getName, "张")));
    }

    /**
     * <p>
     * 参数模式分页
     * </p>
     * <p>
     * 7、分页 size 一页显示数量  current 当前页码
     * 方式一：http://localhost:8080/user/page?size=1&current=1<br>
     * <p>
     * 集合模式，不进行分页直接返回所有结果集：
     * http://localhost:8080/user/page?listMode=true
     */
    @GetMapping("/page")
    public IPage page(Page page, boolean listMode) {
        if (listMode) {
            // size 小于 0 不在查询 total 及分页，自动调整为列表模式。
            // 注意！！这个地方自己控制好！！
            page.setSize(-1);
        }
        return userService.page(page, null);
    }

    /**
     * 测试事物
     * http://localhost:8080/user/test_transactional<br>
     * 访问如下并未发现插入数据说明事物可靠！！<br>
     * http://localhost:8080/user/test<br>
     * <br>
     * 启动  Application 加上 @EnableTransactionManagement 注解其实可无默认貌似就开启了<br>
     * 需要事物的方法加上 @Transactional 必须的哦！！
     */
    @Transactional(rollbackFor = Exception.class)
    @GetMapping("/test_transactional")
    public void testTransactional() {
        User user = new User("测试事物", AgeEnum.ONE, 3);
        userService.save(user);
        System.out.println(" 这里手动抛出异常，自动回滚数据");
        throw new RuntimeException();
    }
}
